package main

import (
	"changeme/backend/dialog"
	"changeme/backend/download"
	"changeme/backend/file"
	"changeme/backend/request"
	"changeme/backend/system"
	"context"
	"encoding/json"
	"fmt"
	"github.com/wailsapp/wails/v2/pkg/menu"
	"github.com/wailsapp/wails/v2/pkg/runtime"
)

// App struct
type App struct {
	ctx     context.Context
	request *request.Request
}

// NewApp creates a new App application struct
func NewApp() *App {
	return &App{
		request: new(request.Request),
	}
}

// startup is called at application startup
func (b *App) startup(ctx context.Context) {
	// Perform your setup here
	b.ctx = ctx

	runtime.EventsOn(ctx, file.EventName, func(optionalData ...interface{}) {
		EventsHandler(file.EventsHandler, ctx, optionalData...)
	})

	runtime.EventsOn(ctx, system.EventName, func(optionalData ...interface{}) {
		EventsHandler(system.EventsHandler, ctx, optionalData...)
	})

	runtime.EventsOn(ctx, dialog.EventName, func(optionalData ...interface{}) {
		EventsHandler(dialog.EventsHandler, ctx, optionalData...)
	})

	runtime.EventsOn(ctx, "download", func(optionalData ...interface{}) {
		EventsHandler(download.EventsHandler, ctx, optionalData...)
	})

	runtime.EventsOn(ctx, "request", func(optionalData ...interface{}) {
		EventsHandler(request.EventsHandler, ctx, optionalData...)
	})

	// 使用 base64 编码传递文件
	runtime.EventsOn(ctx, "test", func(optionalData ...interface{}) {
		EventsHandler(func(ctx context.Context, optionalData ...interface{}) {
			type Test struct {
				// []byte 会被 json 库 转换为 base64 编码
				Data []byte
			}
			data := &Test{}
			err := json.Unmarshal([]byte(optionalData[0].(string)), data)
			runtime.LogDebugf(ctx, "%+v", err)
			runtime.EventsEmit(ctx, "test:resp", data)
		}, ctx, optionalData...)
	})
}

// domReady is called after the front-end dom has been loaded
func (b App) domReady(ctx context.Context) {
	// Add your action here
}

// shutdown is called at application termination
func (b *App) shutdown(ctx context.Context) {
	// Perform your teardown here
}

// Greet returns a greeting for the given name
func (b *App) Greet(name string) string {
	return fmt.Sprintf("Hello %s, It's show time!", name)
}

func (b *App) applicationMenu() *menu.Menu {
	return nil
}

func EventsHandler(handler func(context.Context, ...interface{}), ctx context.Context, optionalData ...interface{}) {
	go func() {
		defer func() {
			if err := recover(); err != nil {
				runtime.LogErrorf(ctx, "[!致命错误!] %+v", err)
			}
		}()

		handler(ctx, optionalData...)
	}()
}
